package com.xcesys.extras.remoting;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.dozer.Mapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * A default {@link IDataObjectHelper} implementation class that uses CGLib as
 * bean properties copy utility.
 * <p>
 * User may sub-class from this to extends his own
 * {@link #copyProperties(Object, Object)} logic.
 * 
 * @author Danne
 * 
 */
@Component("dozerDataObjectHelper")
public class DozerDataObjectHelper implements IDataObjectHelper {

	protected final static Log log = LogFactory
			.getLog(DozerDataObjectHelper.class);

	@Autowired
	private Mapper mapper;

	@Override
	@SuppressWarnings("unchecked")
	public <T> Collection<T> copyProperties(Class<T> toClazz,
			Collection<?> froms) {
		if (froms == null) {
			return null;
		}
		Collection<T> toList = null;
		try {
			toList = froms.getClass().newInstance();
			if (froms instanceof List) {
				toList = new ArrayList<T>();
			} else if (froms instanceof Set) {
				toList = new HashSet<T>();
			}

			for (Object obj : froms) {
				T to = copyProperties(toClazz, obj);
				toList.add(to);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return toList;
	}

	@Override
	public <T> T copyProperties(Class<T> toClazz, Object from) {
		if (from == null) {
			return null;
		}
		return mapper.map(from, toClazz);
		// T to = null;
		// try {
		// to = toClazz.newInstance();
		// } catch (Exception e) {
		// log.error(e);
		// throw new SystemException("SE0015");
		// }
		// copyProperties(to, from);
		// return to;
	}

	@Override
	public <T> Collection<T> copyProperties(Class<T> toClazz, Object[] froms) {
		if (froms == null)
			return null;
		ArrayList<T> toList = new ArrayList<T>();
		for (Object obj : froms) {
			T to = copyProperties(toClazz, obj);
			toList.add(to);
		}
		return toList;
	}

	@Override
	public void copyProperties(Object to, Object from) {
		if (from == null) {
			return;
		}
		dozerMapper(from, to);
	}

	private void dozerMapper(Object source, Object target) {
		mapper.map(target, source);
	}
}
